package edu.zju.udms.dnavigator.core.extract;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import org.apache.log4j.Logger;

import edu.zju.udms.dnavigator.core.config.Configuration;
import edu.zju.udms.dnavigator.core.entity.Entity;
import edu.zju.udms.dnavigator.core.entity.Record;
import edu.zju.udms.dnavigator.core.entity.Relation;
import edu.zju.udms.dnavigator.core.repository.Repository;
import edu.zju.udms.dnavigator.core.utils.Tuple3;

public class ExtractEngineImpl implements ExtractEngine,Runnable,Observer {

	private static final Logger logger = Logger.getLogger(ExtractEngineImpl.class);
	private Configuration configuration;
	private Repository repository;
	private long extractDuration;
	
	public ExtractEngineImpl(Configuration configuration, Repository repository) {
		this.configuration = configuration;
		this.repository = repository;
		((Observable)configuration).addObserver(this);
		extractDuration = 1000L*Integer.parseInt(configuration.getProperty("extract.duration"));
	}

	public void run() {
		while(true) {
			work();
			try {
				Thread.sleep(extractDuration);
			} catch (InterruptedException e) {
				logger.error("InterruptedException:"+e.getMessage());
			}
		}
	}

	public void work() {
		List<Extractor> extractors = configuration.listExtractors();
		List<Entity> entities = new ArrayList<>();
		List<Relation> relations = new ArrayList<>();
		List<Record> records = new ArrayList<>();
		
		//TODO 并行优化
		for(Extractor extractor : extractors) {
			try {
				Tuple3<List<Entity>, List<Relation>, List<Record>> tempRes = extractor.extract();
				logger.info(String.format("Extractor %s extract %d entites %d relations %d records",
						extractor, tempRes.a.size(), tempRes.b.size(), tempRes.c.size()));
				entities.addAll(tempRes.a);
				relations.addAll(tempRes.b);
				records.addAll(tempRes.c);
			} catch(Exception e) {
				logger.error("", e);
			}
		}
		logger.info(String.format("total %d entities extracted", entities.size()));
		try {
			repository.truncreateEntities(entities);
		} catch (Exception e) {
			logger.error("", e);
		}
		
		for (Entity entity :entities ) {
			try {
				List<Relation> tempRelations = entity.analyze(repository);
				relations.addAll(tempRelations);
			} catch(Exception e) {
				logger.error("", e);
			}
		}
		logger.info(String.format("total %d relations analyzed by entities",relations.size()));
		try {
			repository.truncreateEntities(entities);
			repository.truncreateRelations(relations);
			repository.truncreateRecords(records);
		} catch (Exception e) {
			logger.error("", e);
		}
		logger.info("extract task finish");
	}

	@Override
	public void update(Observable o, Object arg) {
		// TODO 系统配置改变响应
	}
	
}
